﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using VMultiAPI;
using Microsoft.Practices.Prism.ViewModel;
using System.Windows;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace ZSens
{
    public class Layout: ICloneable
    {
        private string displayString;

        public string DisplayString
        {
            get { return displayString; }
            set { displayString = value; }
        }

        public JObject jSerialize()
        {
            JObject layout = new JObject();
            JArray wids = new JArray();
            foreach (Widget widget in widgets)
            {
                wids.Add(widget.jSerialize());
            }

            layout.Add("displayString", displayString);
            layout.Add("widgets", wids);
            return layout;
        }

        public void jDeserialize(JObject jlayout)
        {
            this.displayString = (String)jlayout.GetValue("displayString");
            this.widgets = new List<Widget>();
            JArray wids = (JArray) jlayout.GetValue("widgets");
            foreach (JObject widget in wids)
            {
                this.widgets.Add(Widget.jDeserializeDispatch(widget));
            }
        }
        
        public List<Widget> widgets { get; set;}
        public Layout()
        {
            widgets = new List<Widget>();
        }
        public int Serialize(byte[] data, int idx)
        {
            idx = Serializing.writeIntoByteArray(data, idx, this.displayString);
            idx = Serializing.writeIntoByteArray(data, idx, (byte)widgets.Count);
            for (int i = 0; i < widgets.Count; i++)
            {
                idx = Serializing.writeIntoByteArray(data, idx, (byte)i);
                if (idx < 0 || ((idx = widgets[i].Serialize(data, idx)) < 0))
                    return -1;
            }
            return idx;
        }

        public void DoVMultiUpdate()
        {
            foreach (var widget in widgets)
                foreach (var action in widget.BindedAction)
                    action.DoVMultiUpdate();
        }
        public void CopyFrom(Layout l)
        {
            DisplayString = l.DisplayString;
            widgets.Clear();
            foreach (var item in l.widgets)
            {
                widgets.Add(item.Clone() as Widget);
            }
        }
       
        public object Clone()
        {
            Layout newLayout = new Layout();
            newLayout.displayString = this.displayString;
            foreach (var widget in this.widgets)
            {
                newLayout.widgets.Add(widget.Clone() as Widget);
            }
            return newLayout;
        }

    }
    //TODO : Remove these speclized classes
    class BallanceLayout
        : Layout
    {
        public BallanceLayout()
        {
            DisplayString = "Ballance";
            var ox = new OrientationX();
            ox.BindedAction = new List<Action>
            {
                new PressKeyboardKeyAction(
                    new FloatToBool(ox,0.3f,new Range { Start = 0.4f, End = 0f } ),
                    new List<Keyboard.KeyCode> { Keyboard.KeyCode.KeyLeftArrow }
                    ),
                new PressKeyboardKeyAction (
                    new FloatToBool(ox,0.3f,new Range { Start = 0.6f ,End = 1f} ),
                    new List<Keyboard.KeyCode> { Keyboard.KeyCode.KeyRightArrow }
                    )
            };
            var oy = new OrientationY();
            oy.BindedAction = new List<Action>
            {
                new PressKeyboardKeyAction(
                    new FloatToBool(oy,0.3f,new Range { Start = 0.4f , End = 0f } ),
                    new List<Keyboard.KeyCode> { Keyboard.KeyCode.KeyUpArrow }
                    ),
                new PressKeyboardKeyAction (
                    new FloatToBool(oy,0.3f,new Range { Start = 0.6f ,End = 1f} ),
                    new List<Keyboard.KeyCode> { Keyboard.KeyCode.KeyDownArrow }
                    )
            };
            var but1 = new Button(new Point(20, 35), new Point(40, 75), "Clockwise Rotate");
            but1.BindedAction = new List<Action>
            {
                new PressKeyboardKeyAction(but1,new List<Keyboard.KeyCode>{ Keyboard.KeyCode.KeyLeftShift,Keyboard.KeyCode.KeyLeftArrow } )
            };
            var but2 = new Button(new Point(60, 35), new Point(80, 75), "CounterClockwise Rotate");
            but2.BindedAction = new List<Action>
            {
                new PressKeyboardKeyAction(but2,new List<Keyboard.KeyCode>{ Keyboard.KeyCode.KeyLeftShift,Keyboard.KeyCode.KeyRightArrow } )
            };
            widgets = new List<Widget>
            {
                but1,but2,
                ox,oy
            };
        }
    }

    class NeedForSpeedLayout
        : Layout
    {
        public NeedForSpeedLayout()
        {
            DisplayString = "Need For Speed IX: Most Wanted";
            var ox = new OrientationX();
            ox.BindedAction = new List<Action>
            {
                new SetJoystickAxisAction(ox,JoystickAxis.X)
            };
            var oy = new OrientationY();
            oy.BindedAction = new List<Action>
            {
                new SetJoystickAxisAction(oy,JoystickAxis.Y)
            };
            var but1 = new Button(new Point(20, 35), new Point(40, 75), "ACCELERATE");
            but1.BindedAction = new List<Action>
            {
                new PressJoystickButtonAction(but1,new List<int>{0})
            };
            var but2 = new Button(new Point(60, 35), new Point(80, 75), "BRAKE");
            but2.BindedAction = new List<Action>
            {
                new PressJoystickButtonAction(but2,new List<int>{1})
            };
            widgets = new List<Widget>
            {
                but1,but2,ox,oy 
            };
        }
    }
}
